package com.sakura.probe.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sakura.probe.common.api.CommonResult;
import com.sakura.probe.common.util.PageCalculate;
import com.sakura.probe.mapper.*;
import com.sakura.probe.nosql.elasticsearch.EsSearchService;
import com.sakura.probe.nosql.redis.RedisKey;
import com.sakura.probe.nosql.redis.RedisService;
import com.sakura.probe.pojo.*;
import com.sakura.probe.service.OssService;
import com.sakura.probe.service.TopicService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.List;
import java.util.Set;

@Service
public class TopicServiceImpl extends ServiceImpl<TopicMapper, Topic> implements TopicService {
    @Autowired
    private TopicMapper topicMapper;
    @Autowired
    private TopicImgMapper topicImgMapper;
    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private PersonInfoMapper personMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private OssService ossService;
    @Autowired
    private EsSearchService esSearchService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private TopicCategoryMapper topicCategoryMapper;
    @Autowired
    private FootPrintMapper footPrintMapper;

    @Override
    public CommonResult save(Topic topic, List<MultipartFile> fileList, int type) {
        int effectedNum = topicMapper.insert(topic);
        if (effectedNum>0){
            if (fileList.size()>0){
                boolean result = false;
                if (type==1){
                    result = ossService.batchAddImage(topic.getTopicId(),
                            topic.getPersonInfo().getUsername(), fileList).isSuccess();
                }else {
                    result = ossService.addVideo(topic,fileList).isSuccess();
                }
                if (!result){
                    return CommonResult.failed("上传文件到OSS失败");
                }
            }
            //同时存储一份在elasticsearch中
            boolean esResult = esSearchService.addTopic(new Topic(topic.getTopicId(), topic.getTopicCategoryId(),
                    topic.getTopicName(), 1, new Date(), topic.getTopicCategoryName()));
            if (null!=topic.getEnableHeadline()){
                redisService.remove(RedisKey.getHeadLine());
            }
            return esResult?CommonResult.success("成功发布"):CommonResult.success("插入elasticsearch失败");
        }else {
            return CommonResult.failed("插入mysql失败");
        }
    }

    @Override
    public CommonResult<List<Topic>> listByCondition(Topic topicCondition, int pageIndex, int pageSize) {
        List<Topic> topicList = topicMapper.queryTopicList(topicCondition,
                PageCalculate.calculateRowIndex(pageIndex, pageSize),pageSize);
        //同时添加每个话题相对应的点赞、评论和收藏数
        Topic temp;
        for (int i=0;i<topicList.size();i++){
            temp = topicList.get(i);
            addTCC(temp);
            topicList.set(i,temp);
        }
        return CommonResult.success(topicList);
    }

    @Override
    public Long countByCondition(Topic topic) {
        return topicMapper.queryTopicCount(topic);
    }

    @Override
    public CommonResult<Topic> getTopicInfo(Long topicId, String userId) {
        Topic topic = topicMapper.selectById(topicId);
        //获取话题内容的图片
        List<TopicImg> imgList = topicImgMapper.selectList(new QueryWrapper<TopicImg>().eq("topic_id", topicId));
        topic.setTopicImgList(imgList);
        //获取话题内容的视频
        Video video = videoMapper.selectOne(new QueryWrapper<Video>().eq("topic_id", topicId));
        topic.setVideo(video);
        //获取楼主的相关信息
        PersonInfo person= personMapper.selectById(topic.getOwnerId());
        topic.setPersonInfo(person);
        //获取该话题的相关类型
        topic.setTopicCategoryName(topicCategoryMapper.selectById(topic.getTopicCategoryId()).getTopicCategoryName());
        //判断当前浏览的用户是否对该话题进行点赞或收藏
        Set<String> personThumbSet = redisService.getSet(RedisKey.getPersonThumb() + userId);
        Set<String> personCollectSet = redisService.getSet(RedisKey.getPersonCollect() + userId);
        if (null!=personCollectSet&&personCollectSet.contains(topicId+"")){
            topic.setCollect(true);
        }
        if (null!=personThumbSet&&personThumbSet.contains(topicId+"")){
            topic.setThumb(true);
        }
        redisService.setSet(RedisKey.getPersonThumb() + userId,personThumbSet);
        redisService.setSet(RedisKey.getPersonCollect() + userId,personCollectSet);
        addTCC(topic);
        return CommonResult.success(topic);
    }

    @Override
    public boolean deleteTopic(Long topicId) {
        try {
            commentMapper.delete(new QueryWrapper<Comment>().eq("topic_id", topicId));
            delVideo(topicId);
            delTopicImage(topicId);
            footPrintMapper.delete(new QueryWrapper<FootPrint>().eq("topic_id",topicId));
            topicMapper.deleteTopicById(topicId);
            //接着删除elasticsearch中相关的存储信息
            esSearchService.deleteTopic(topicId);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**根据topicId删除话题视频*/
    private void delVideo(Long topicId) {
        List<Video> list = videoMapper.selectList(new QueryWrapper<Video>().eq("topic_id", topicId));
        for (Video video:list){
            //根据url进行删除
            ossService.deleteImage(video.getVideoUrl());
        }
        //最后再删除Mysql中的数据
        videoMapper.delete(new QueryWrapper<Video>().eq("topic_id", topicId));
    }

    /**根据topicId删除话题图片*/
    private void delTopicImage(Long topicId){
        List<TopicImg> list = topicImgMapper.selectList(new QueryWrapper<TopicImg>().eq("topic_id", topicId));
        for (TopicImg topicImg:list){
            ossService.deleteImage(topicImg.getImgAddr());
        }
        topicImgMapper.delete(new QueryWrapper<TopicImg>().eq("topic_id",topicId));
    }

    @Override
    public boolean batchDeleteTopic(List<Long> list) {
        try {
            if (null!=list&&!list.isEmpty()){
                for (Long topicId:list){
                    deleteTopic(topicId);
                }
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Override
    public boolean restoreTopic(Long topicId) {
        Topic condition = new Topic();
        condition.setTopicId(topicId).setDeleted(0);
        return topicMapper.updateTopic(condition)>0?true:false;
    }

    @Override
    public boolean batchRestoreTopic(List<Long> list) {
        try {
            Topic topic = new Topic();
            topic.setDeleted(0);
            for (Long topicId:list){
                topic.setTopicId(topicId);
                topicMapper.updateTopic(topic);
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }


    /**
     * 添加点赞、收藏和评论的数量
     * @param topic
     */
    public void addTCC(Topic topic){
        Long topicId = topic.getTopicId();
        //同时获取该用户的点赞、收藏和评论数
        String thumbNum = redisService.get(RedisKey.getThumbTopicIdList() + topicId);
        String collectNum = redisService.get(RedisKey.getCollectTopicIdList() + topicId);
        if ("null".equals(thumbNum)){
            thumbNum = 0+"";
        }
        if ("null".equals(collectNum)){
            collectNum = 0 + "";
        }
        topic.setTopicThumbNum(Integer.valueOf(thumbNum));
        topic.setTopicCollectionNum(Integer.valueOf(collectNum));
        //评论数
        Integer commentNum = commentMapper.selectCount(new QueryWrapper<Comment>().eq("topic_id", topicId));
        topic.setTopicDiscussNum(commentNum);
    }

}

